//todo 定义字符串
let str: string = "hello";
// ts有自动类型推断
let str2: string;
str2 = "world";
// str2.split("");

//todo 定义数字
let num: number = 3;
num = 5;
// num.split("");

//todo 定义布尔值
//todo true和false
let done: boolean = true;
done = false;

//todo 定义undefined
let udf: undefined = undefined;

//todo 定义null
let nl: null = null;

//todo 联合类型
let a: number | string | boolean = 3;
a = "hello";
a = true;

// const token: string | null = localStorage.getItem("token");
// if (token) {
//   token.split("");
// }

//todo 任何类型
let b: any = 3;
b = "3";
b = {
  a: 100,
};

//todo 数组类型
let arr: number[] = [1, 2, 3, 4];
let arr2: Array<number> = [1, 2, 3, 4];
let arr3: (number | string | boolean)[] = [1, "2", true];
let arr4: Array<number | string | boolean> = [1, "2", true];
let arr5: (number | number[])[] = [1, 2, [3, 4, 5]];

//todo 元组类型
// 元组就是数组，只是规定了数组的长度，以及每一项的类型
let arr6: [number, boolean] = [1, true];
// arr6 = [...arr6, 6]
// console.log(arr6[2]);

//todo 对象类型
interface ObjType {
  name: string;
  age: number;
  // ？表示可选属性
  address?: string;
  // 索引签名
  // 表示剩下的属性随意
  [propname: string]: any;
}
// let obj = {
//   name: "zhangsan",
//   age: 20,
// } as ObjType;
let obj: ObjType = {
  name: "zhangsan",
  age: 20,
  a: 3,
  b: true,
};
obj.address = "jiubao";

interface SanweiType {
  touwei: number;
  xiongwei: number;
  tuowei: number;
}
interface ZhangmouType {
  name: string;
  age: number;
  likes: number[];
  sanwei: SanweiType;
}
let obj2 = {
  name: "zhangmou",
  age: 20,
  likes: [298, 398, 698],
  sanwei: {
    touwei: 100,
    xiongwei: 200,
    tuowei: 800,
  },
};

interface ItemType {
  id: number;
  name: string;
}
let arr7: ItemType[] = [
  { id: 1, name: "zhangmou" },
  { id: 2, name: "junmou" },
];

//todo 枚举类型
enum Color {
  Red,
  Green = 10,
  Blue,
}
let green: Color = Color.Green;
// console.log(green);
let colorname: string = Color[10];
// console.log(colorname);

//todo 函数类型
// 函数的类型写的是返回值的类型
function add(): number {
  return 10;
}
// 绝大多数的情况下，ts是有类型推断的，但是函数参数是没有推断的
function add2(x: number, y: string): string {
  return x + y;
}
add2(3, "4");
// ？表示可选参数
function add3(x: number, y?: number): number {
  return y ? x + y : x;
}
add3(100);

const add4: (x: number, y: number) => number = (
  x: number,
  y: number
): number => {
  return x + y;
};
add4(3, 4);

//todo void类型表示没有返回值
const fn = (): void => {
  console.log(123);
};

//todo never类型表示没有类型
const fn1 = (): never => {
  throw new Error("xxx");
};
const fn2 = (): never => {
  while (true) {}
};

//todo 泛型类型
function fn3<T>(x: T, y: T) {
  return 5;
}
fn3<number>(3, 4);
// const count = ref<number>(3);
// const doubleCount = computed<number>(() => {})

//todo 类类型
interface ParamsType {
  name: string;
}
class Animal {
  constructor(obj: ParamsType) {
    this.name = obj.name;
  }
  name: string = "cat";
  sayName(): string {
    return this.name;
  }
}
// 类的继承
class Cat extends Animal {
  // constructor函数是在这个类被实例化的时候调用的
  // super方法调用就相当于调用父类的constructor
  constructor(obj: ParamsType) {
    super(obj);
  }
}
// 创建实例
const cat = new Cat({
  name: "dog",
});

console.log(cat.name); // dog
console.log(cat.sayName());
